稍微題外話的補充一下交易所的錢包類型,中心化交易所的話通常會有之前提到的兩種錢包也就是冷熱錢包,但是後面有發展出一個錢包也就是溫錢包,
冷錢包:用來保管全公司的所有加密資產
熱錢包:由註記詞和path衍生出的address,用於提供給使用者
溫錢包:一種概念但本體是冷錢包
這些的用途是
熱錢包:提供給使用者deposit加密資產進來的address,收到加密資產後會馬上轉移至冷錢包。
溫錢包:使用者在withdraw到外部時,如果轉移資產小於設定值(例如等值5000美金)的話則會自動提交交易。
冷錢包:當轉移資產大於設定值(例如等值5000美金),則需要多人簽署放行,例如將私鑰分散在四人身上,今天只有這四人簽署交易,才能正式的將交易上鏈。
昨天設計的API接口需要重整一下,在讀完REST API Design Best Practices for Sub and Nested Resources後需要做點調整。
原本的:
# 建立錢包 GET
/api/v1/wallet/mnemonic
# 取得pem GET
/api/v1/wallet/pem
# 登入錢包 POST
/api/v1/wallet/login
# 查詢餘額 GET
/api/v1/wallet/balance
# 提交轉帳 POST
/api/v1/wallet/withdraw
修改後:
# 建立錢包 GET
/api/v1/wallet/mnemonic
# 取得pem POST
/api/v1/wallet/pem
# 登入錢包 POST
/api/v1/wallet/:Address/login
# 查詢餘額 GET
/api/v1/wallet/:Address/balance
# 提交轉帳 POST
/api/v1/wallet/:Address/withdraw
我自己在嘗試開發新的框架時,會習慣去github找xxx best practice,直接從臨摹開始從他們裡面去學習他們這樣設計的思維,這次我參考的是gin-restful-best-practice所分享的架構概念。
首先安裝Gin
go get -u github.com/gin-gonic/gin
這是新增的架構
server.go 啟動Gin port設定為5001
package main
import (
"elrondWallet/api/routes"
"log"
)
func main() {
engine := routes.New()
log.Fatal(engine.Run(":5001"))
}
router.go 啟動路由引擎
package routes
import "github.com/gin-gonic/gin"
var engine = gin.Default()
func New() *gin.Engine {
return engine
}
api.go api接口
package routes
import "elrondWallet/api/controllers"
func init() {
// unauthorized
unauthorizedAPI := engine.Group("api/v1/wallet")
{
unauthorizedAPI.GET("/mnemonic", controllers.Mnemonic)
unauthorizedAPI.POST("/pem", controllers.DownloadPem)
//unauthorizedAPI.POST("/:address/login", controllers.CreateUser)
//unauthorizedAPI.GET("/:address/balance", controllers.CreateUser)
//unauthorizedAPI.POST("/:address/withdraw", controllers.CreateUser)
}
}
wallet.go controllers 負責處理邏輯
package controllers
import (
walletUtils "elrondWallet/internal/wallet"
"github.com/gin-gonic/gin"
)
func Mnemonic(c *gin.Context) {
mnemonic, _ := walletUtils.GenerateNewMnemonic()
c.JSON(200, gin.H{
"code": "00",
"mnemonic": mnemonic,
})
}
type MnemonicReq struct {
Mnemonic string `json:"mnemonic"`
}
func DownloadPem(c *gin.Context) {
var ap MnemonicReq
if err := c.ShouldBindJSON(&ap); err != nil {
c.JSON(400, gin.H{"error": "Calculator error"})
return
}
privateKey := walletUtils.GetPrivateKeyFromMnemonic(ap.Mnemonic, 0, 0)
address, _ := walletUtils.GetAddressFromPrivateKey(privateKey)
err := walletUtils.SavePrivateKeyToPemFile(privateKey, address)
if err != nil {
return
}
c.Header("Content-Description", "File Transfer")
c.Header("Content-Transfer-Encoding", "binary")
c.Header("Content-Disposition", "attachment; filename="+address+".pem")
c.Header("Content-Type", "application/octet-stream")
c.File(address + ".pem")
}
今天完成的gin架構設計以及實現了取得新的助記詞和下載pem的API
明天就是挑戰最後一天了,完成剩下的API就能做個收尾了。